import * as Cesium from 'cesium';

/**
 * Animation utility functions
 */

/**
 * Create a polygon with animated material
 * @param {Cesium.Viewer} viewer - The Cesium viewer instance
 * @param {Object} options - Polygon options
 * @param {Array} options.positions - Array of longitude/latitude pairs
 * @param {Cesium.Color} options.color - Base color
 * @param {Number} options.extrudedHeight - Extrusion height
 * @param {String} options.name - Polygon name
 * @param {Function} options.alphaFunction - Function to calculate alpha value
 */
export function createAnimatedPolygon(viewer, options) {
  const {
    positions,
    color = Cesium.Color.WHITE,
    extrudedHeight = 0,
    name = 'Polygon',
    alphaFunction = () => 0.5
  } = options;
  
  return viewer.entities.add({
    name,
    polygon: {
      hierarchy: Cesium.Cartesian3.fromDegreesArray(positions),
      material: new Cesium.ColorMaterialProperty(
        new Cesium.CallbackProperty(() => {
          const alpha = alphaFunction();
          return new Cesium.Color(
            color.red,
            color.green,
            color.blue,
            alpha
          );
        }, false) // isConstant = false
      ),
      outline: true,
      outlineColor: Cesium.Color.WHITE,
      height: 0,
      extrudedHeight
    }
  });
}

/**
 * Create an animated point
 * @param {Cesium.Viewer} viewer - The Cesium viewer instance
 * @param {Object} options - Point options
 * @param {Number} options.lon - Longitude
 * @param {Number} options.lat - Latitude
 * @param {Cesium.Color} options.color - Point color
 * @param {String} options.name - Point name
 * @param {Function} options.sizeFunction - Function to calculate point size
 */
export function createAnimatedPoint(viewer, options) {
  const {
    lon,
    lat,
    color = Cesium.Color.WHITE,
    name = 'Point',
    sizeFunction = () => 10
  } = options;
  
  return viewer.entities.add({
    name,
    position: Cesium.Cartesian3.fromDegrees(lon, lat),
    point: {
      pixelSize: new Cesium.CallbackProperty(() => {
        return sizeFunction();
      }, false), // isConstant = false
      color,
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2
    }
  });
}

/**
 * Create an animated billboard
 * @param {Cesium.Viewer} viewer - The Cesium viewer instance
 * @param {Object} options - Billboard options
 * @param {Number} options.lon - Longitude
 * @param {Number} options.lat - Latitude
 * @param {String} options.image - Image URL
 * @param {String} options.name - Billboard name
 * @param {Function} options.scaleFunction - Function to calculate scale
 * @param {Function} options.colorFunction - Function to calculate color
 */
export function createAnimatedBillboard(viewer, options) {
  const {
    lon,
    lat,
    image,
    name = 'Billboard',
    scaleFunction = () => 1.0,
    colorFunction = () => Cesium.Color.WHITE
  } = options;
  
  return viewer.entities.add({
    name,
    position: Cesium.Cartesian3.fromDegrees(lon, lat),
    billboard: {
      image,
      scale: new Cesium.CallbackProperty(() => {
        return scaleFunction();
      }, false), // isConstant = false
      color: new Cesium.CallbackProperty(() => {
        return colorFunction();
      }, false) // isConstant = false
    }
  });
}

/**
 * Create a moving entity along a path
 * @param {Cesium.Viewer} viewer - The Cesium viewer instance
 * @param {Object} options - Path options
 * @param {Array} options.positions - Array of [longitude, latitude] pairs
 * @param {Number} options.duration - Duration in seconds
 * @param {Cesium.Color} options.color - Entity color
 * @param {String} options.name - Entity name
 * @param {Object} options.pathOptions - Path visualization options
 */
export function createPathAnimation(viewer, options) {
  const {
    positions,
    duration = 30,
    color = Cesium.Color.RED,
    name = 'Moving Entity',
    pathOptions = {}
  } = options;
  
  if (positions.length < 2) {
    throw new Error('At least 2 positions are required for a path');
  }
  
  // Convert positions to Cartesian3
  const cartesianPositions = positions.map(pos => 
    Cesium.Cartesian3.fromDegrees(pos[0], pos[1])
  );
  
  // Create position property
  const position = new Cesium.SampledPositionProperty();
  
  // Add sample points
  const start = Cesium.JulianDate.fromDate(new Date());
  let currentTime = start.clone();
  
  cartesianPositions.forEach((cartesianPos) => {
    position.addSample(currentTime, cartesianPos);
    currentTime = Cesium.JulianDate.addSeconds(
      currentTime, 
      duration / (cartesianPositions.length - 1), 
      new Cesium.JulianDate()
    );
  });
  
  const end = currentTime;
  
  // Default path options
  const defaultPathOptions = {
    show: true,
    leadTime: 0,
    trailTime: duration,
    width: 3,
    material: new Cesium.PolylineGlowMaterialProperty({
      glowPower: 0.1,
      color: Cesium.Color.YELLOW
    }),
    resolution: 1
  };
  
  const finalPathOptions = { ...defaultPathOptions, ...pathOptions };
  
  // Create entity
  const entity = viewer.entities.add({
    name,
    position: position,
    point: {
      pixelSize: 10,
      color: color,
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2
    },
    label: {
      text: name,
      font: '14px sans-serif',
      fillColor: Cesium.Color.WHITE,
      outlineColor: Cesium.Color.BLACK,
      outlineWidth: 2,
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(0, -15)
    },
    path: finalPathOptions
  });
  
  // Set clock
  viewer.clock.startTime = start.clone();
  viewer.clock.stopTime = end.clone();
  viewer.clock.currentTime = start.clone();
  viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
  viewer.clock.multiplier = 5;
  
  return entity;
}

export default {
  createAnimatedPolygon,
  createAnimatedPoint,
  createAnimatedBillboard,
  createPathAnimation
};